Change the XSettingsWatchFunc to return a Bool to indicate success. Update
authorMatthias Clasen <mclasen@redhat.com>
Tue, 10 Apr 2007 23:16:30 +0000 (23:16 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Tue, 10 Apr 2007 23:16:30 +0000 (23:16 +0000)
2007-04-10  Matthias Clasen  <mclasen@redhat.com>

        * gdk/x11/xsettings-client.[hc]: Change the XSettingsWatchFunc
        to return a Bool to indicate success. Update callers and
        implementors. Based on a patch by Owen Taylor.

        * gdk/x11/gdkevents-x11.c (gdk_xsettings_watch_cb): Don't
        leak a reference to gdkwin.

svn path=/trunk/; revision=17592

ChangeLog
gdk/x11/gdkevents-x11.c
gdk/x11/xsettings-client.c
gdk/x11/xsettings-client.h

index e234a7b8fba415c788d39bf5d35e0567d6b2c7f0..7ac03789a159d1afe5d8c5a423f8d17d69dfcea4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-04-10  Matthias Clasen  <mclasen@redhat.com>
+
+       * gdk/x11/xsettings-client.[hc]: Change the XSettingsWatchFunc
+       to return a Bool to indicate success. Update callers and 
+       implementors. Based on a patch by Owen Taylor.
+       
+       * gdk/x11/gdkevents-x11.c (gdk_xsettings_watch_cb): Don't
+       leak a reference to gdkwin.
+
 2007-04-07  Xan Lopez  <xan@gnome.org>
 
        * gtk/gtknotebook.c (gtk_notebook_class_init): 
index 7cdfc88450b774360babec8b1b938ef87d85fa60..6df08bb3df4390f4259e1d4ea76a7f27fb203e92 100644 (file)
@@ -111,7 +111,7 @@ static GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev,
 static GSource *gdk_display_source_new (GdkDisplay *display);
 static gboolean gdk_check_xpending     (GdkDisplay *display);
 
-static void gdk_xsettings_watch_cb  (Window            window,
+static Bool gdk_xsettings_watch_cb  (Window            window,
                                     Bool              is_start,
                                     long              mask,
                                     void             *cb_data);
@@ -2993,7 +2993,7 @@ gdk_xsettings_client_event_filter (GdkXEvent *xevent,
     return GDK_FILTER_CONTINUE;
 }
 
-static void 
+static Bool
 gdk_xsettings_watch_cb (Window   window,
                        Bool     is_start,
                        long     mask,
@@ -3006,16 +3006,39 @@ gdk_xsettings_watch_cb (Window   window,
 
   if (is_start)
     {
-      if (!gdkwin)
-       gdkwin = gdk_window_foreign_new_for_display (gdk_screen_get_display (screen), window);
-      
+      if (gdkwin)
+       g_object_ref (gdkwin);
+      else
+       {
+         gdkwin = gdk_window_foreign_new_for_display (gdk_screen_get_display (screen), window);
+         
+         /* gdk_window_foreign_new_for_display() can fail and return NULL if the
+          * window has already been destroyed.
+          */
+         if (!gdkwin)
+           return False;
+       }
+
       gdk_window_add_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
     }
   else
     {
-      if (gdkwin)
-        gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
+      if (!gdkwin)
+       {
+         /* gdkwin should not be NULL here, since if starting the watch succeeded
+          * we have a reference on the window. It might mean that the caller didn't
+          * remove the watch when it got a DestroyNotify event. Or maybe the
+          * caller ignored the return value when starting the watch failed.
+          */
+         g_warning ("gdk_xsettings_watch_cb(): Couldn't find window to unwatch");
+         return False;
+       }
+      
+      gdk_window_remove_filter (gdkwin, gdk_xsettings_client_event_filter, screen);
+      g_object_unref (gdkwin);
     }
+
+  return True;
 }
 
 #define __GDK_EVENTS_X11_C__
index d17e4213a6c2e5e60f54ccde5a8cae5b7483dc9d..93e0d7e1b26865e20c067cb96d0bea83e0c1b518 100644 (file)
@@ -441,9 +441,19 @@ check_manager_window (XSettingsClient *client)
   XFlush (client->display);
 
   if (client->manager_window && client->watch)
-    client->watch (client->manager_window, True, 
-                  PropertyChangeMask | StructureNotifyMask,
-                  client->cb_data);
+    {
+      if (!client->watch (client->manager_window, True, 
+                         PropertyChangeMask | StructureNotifyMask,
+                         client->cb_data))
+       {
+         /* Inability to watch the window probably means that it was destroyed
+          * after we ungrabbed
+          */
+         client->manager_window = None;
+         return;
+       }
+    }
+      
   
   read_settings (client);
 }
index ba34130107aa75159efb57a964188172175db152..710ed12482d3251d352bc47a29e8bb8410241772 100644 (file)
@@ -43,7 +43,7 @@ typedef void (*XSettingsNotifyFunc) (const char       *name,
                                     XSettingsAction   action,
                                     XSettingsSetting *setting,
                                     void             *cb_data);
-typedef void (*XSettingsWatchFunc)  (Window            window,
+typedef Bool (*XSettingsWatchFunc)  (Window            window,
                                     Bool              is_start,
                                     long              mask,
                                     void             *cb_data);